/**
 * Copyright (c) 2010
 * Bert Young. UESTC. 
 */
 
#ifndef BERT_TCPTaskPOOL_H
#define BERT_TCPTaskPOOL_H

#include "debug.h"
#include <list>
#include <string>
#include <errno.h>
#include "TCPTask.h"
#include "TaskQueue.h"
#include "RunnableEntry.h"

class TCPTaskPool;

class VerifyThread : public RunnableEntry, private TaskQueue<TCPTask>
{
public:
	/**
	 * 避免public继承
	 */
	using TaskQueue<TCPTask>::addTask;

private:
	/**
	 * 父类含有一个queue<TCPTask>
	 * 每个验证线程含有一个epoll符，监视queue
	 */
	TCPTaskPool * pool;
	/**
	 * 等待验证的连接
	 */
	std::list<TCPTask *> tasks;
	/**
	 * 等待验证的连接数
	 */
	int taskcount;
	/**
	 * Epoll the tasks
	 */
	int epfd;
	/**
	 * Epoll events
	 */
	std::vector<struct epoll_event> events;
	/**
	 * Put a task to task list
	 */
	virtual void _add(TCPTask * task );
	/**
	 * Remove a task from task list
	 */
	void remove(std::list<TCPTask *>::iterator & iter);
	/**
	 * Remove a task from task list
	 */
	void remove(TCPTask * task );
public:
	/**
	 * Tasks per thread dealing
	 */
	static const int max_task_size = 1024;
	/**
	 * Constructor
	 */
	VerifyThread(const std::string & name="VerifyThread" ) : RunnableEntry(name)
	{
		this->pool = NULL;
		this->taskcount = 0;
		this->epfd = epoll_create(256);
		this->events.resize(256);
#ifdef CHINESE
		debug("验证线程创建epoll监视符 %d", epfd);
#else
		debug("%s creat verify epollfd %d", __PRETTY_FUNCTION__, epfd);
#endif
	}
	/**
	 * Destructor
	 */
	~VerifyThread( )
	{
#ifdef CHINESE
		debug("验证线程关闭epoll监视符 %d", epfd);
#else
		debug("%s close verify epollfd %d", __PRETTY_FUNCTION__, epfd);
#endif
		TEMP_FAILURE_RETRY(::close(this->epfd));
	}
	/**
	 * All tasks
	 */
	int taskSize() const
	{
		return this->taskcount + getTaskCount();
	}
	/**
	 * Max capacity per thread
	 */
	int maxTaskSize() const
	{
		return max_task_size;
	}
	/**
	 * Set owner
	 */
	void initPool( void * pool)
	{
		this->pool = (TCPTaskPool *) pool;
	}

	/**
	 * wait for verifyConn success or fail or timeout
	 */
	void run( );
};

//////////////////////////////////////////////////////////////////
class OkayThread : public RunnableEntry, private TaskQueue<TCPTask>
{
public:
	/**
	 * 避免public继承
	 */
	using TaskQueue<TCPTask>::addTask;
	
private:
	/**
	 * owner threads pool
	 */
	TCPTaskPool * pool;
	/**
	 * 正在处理的连接
	 */
	std::list<TCPTask *> tasks;
	/**
	 * 正在处理的连接数目
	 */
	int taskcount;
	/**
	 * Epoll the tasks
	 */
	int epfd;
	/**
	 * Epoll events
	 */
	std::vector<struct epoll_event> events;
	/**
	 * Put a task to task list
	 */
	virtual void _add(TCPTask * task );
	/**
	 * Remove a task from task list
	 */
	void remove(std::list<TCPTask *>::iterator & iter);
public:
	/**
	 * Tasks per thread dealing
	 */
	static const int max_task_size = 512;
	/**
	 * Constructor
	 */
	OkayThread(const std::string & name="OkayThread" ) : RunnableEntry(name)
	{
		this->pool = NULL;
		this->taskcount = 0;
		this->epfd = epoll_create(max_task_size);
		this->events.resize(max_task_size);
#ifdef CHINESE
		debug("okay线程创建epoll监视符%d", epfd);
#else
		debug("%s creat okay epollfd %d", __PRETTY_FUNCTION__, epfd);
#endif
	}
	/**
	 * Destructor
	 */
	~OkayThread( )
	{
#ifdef CHINESE
		debug("%s okay线程关闭epoll监视符%d", __PRETTY_FUNCTION__, epfd);
#else
		debug("%s =close okay epollfd %d", __PRETTY_FUNCTION__, epfd);
#endif
		TEMP_FAILURE_RETRY(::close(this->epfd));
	}
	/**
	 * All tasks
	 */
	int taskSize() const
	{
		return this->taskcount + getTaskCount();
	}
	/**
	 * Max capacity per thread
	 */
	int maxTaskSize() const
	{
		return max_task_size;
	}
	/**
	 * Set owner
	 */
	void initPool( void * pool)
	{
		this->pool = (TCPTaskPool *) pool;
	}
	/**
	 * Do the IO
	 */
	void run( );
};
//////////////////////////////////////////////
class RecycleThread : public RunnableEntry, TaskQueue<TCPTask>
{
	friend class TCPTaskPool;
public:
	/**
	 * 避免public继承
	 */
	using TaskQueue<TCPTask>::addTask;

private:
	/**
	 * owner threads pool
	 */
	TCPTaskPool * pool;
	/**
	 * 正在处理的连接
	 */
	std::list<TCPTask *> tasks;
	/**
	 * Put a task to task list
	 */
	virtual void _add(TCPTask * task );
public:
	/**
	 * Tasks per thread dealing
	 */
	static const int max_task_size = 65534;
	/**
	 * Constructor
	 */
	RecycleThread(const std::string & name="RecycleThread" ) : RunnableEntry(name)
	{
		pool = NULL;
	}
	/**
	 * All tasks
	 */
	int taskSize() const
	{
		return tasks.size() + getTaskCount();;
	}
	/**
	 * Max capacity per thread
	 */
	int maxTaskSize() const
	{
		return max_task_size;
	}
	/**
	 * Set owner
	 */
	void initPool( void * pool)
	{
		this->pool = (TCPTaskPool *) pool;
	}
	/**
	 * Do the IO
	 */
	void run( );
};

///////////////////////////////////////////////
///////////////////////////////////////////////
///////////////////////////////////////////////
class TCPTaskPool : private Noncopyable
{
	/**
	 * Okay threads total max capacity
	 */
	const int maxConns;
	/**
	 * 多个验证线程
	 */
	RunnableManager<VerifyThread> verifyThreads;
	/**
	 * Okay thread多个
	 */
	RunnableManager<OkayThread> okayThreads;
	/**
	 * 一个回收线程
	 */
	RunnableManager<RecycleThread> recycleThreads;
public:
	static long usleep_time;

	explicit TCPTaskPool(int maxConns, int us = 50000) : maxConns(maxConns)
	{
		usleep_time = us;
	}
	~TCPTaskPool()
	{
		//this->finally();
	}
	int getSize()
	{
		return okayThreads.taskCount();
	}
	bool addVerify(TCPTask * task);
	bool addOkay(TCPTask * task);
	void addRecycle(TCPTask * task);

	bool init();

	void finally();
};

#endif
